Functional Composition একটি শক্তিশালী ধারণা ফাংশনাল প্রোগ্রামিংয়ের মধ্যে, যেখানে ছোট ছোট ফাংশনগুলো একে অপরের সাথে যুক্ত হয়ে একটি বড় ফাংশন তৈরি করে। এটি ফাংশনগুলিকে একত্রিত করার একটি পদ্ধতি, যেখানে আউটপুট হিসাবে একটি ফাংশনকে ইনপুট হিসেবে অন্য ফাংশনে পাঠানো হয়। ফাংশনাল কম্পোজিশন মূলত একাধিক ফাংশনকে একটি সঙ্গতিপূর্ণ একক ফাংশনে একত্রিত করার কাজ করে।
Java 8-এ Functional Programming প্যাটার্নে Function Composition করা অনেক সহজ হয়ে গেছে, বিশেষ করে lambda expressions এবং functional interfaces এর মাধ্যমে।
1. Functional Composition কী?
Functional Composition হল একটি ধারণা যেখানে একাধিক ফাংশন একত্রিত হয়ে একটি নতুন ফাংশন তৈরি করে। এটি প্রধানত higher-order functions এর মাধ্যমে কাজ করে, যেখানে ফাংশন গুলি অন্য ফাংশনকে আর্গুমেন্ট হিসেবে গ্রহণ করে এবং একটি নতুন ফাংশন রিটার্ন করে।
ফাংশনাল কম্পোজিশনে দুটি ফাংশনকে একত্রিত করা হয়:
- First function (f): প্রথম ফাংশন ইনপুট নিয়ে প্রক্রিয়া করে আউটপুট দেয়।
- Second function (g): প্রথম ফাংশনের আউটপুট হিসেবে প্রাপ্ত মানকে ইনপুট হিসেবে গ্রহণ করে এবং নিজের প্রক্রিয়া সম্পন্ন করে।
ফাংশনাল কম্পোজিশনের মাধ্যমে এই দুটি ফাংশনকে একত্রিত করা হয় যাতে g(f(x)) তৈরি হয়।
2. Function Composition in Java
Java 8 এর পরে, java.util.function প্যাকেজে Function ইন্টারফেসের মধ্যে compose() এবং andThen() মেথডের মাধ্যমে ফাংশনাল কম্পোজিশন সমর্থন করা হয়।
Function Interface:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
return (T t) -> after.apply(apply(t));
}
}
compose(): এই মেথডটি বর্তমান ফাংশনের আগে অন্য একটি ফাংশন প্রয়োগ করে। এটি মূলত g(f(x)) প্যাটার্ন অনুসরণ করে।andThen(): এই মেথডটি বর্তমান ফাংশনের পরে অন্য একটি ফাংশন প্রয়োগ করে। এটি মূলত f(g(x)) প্যাটার্ন অনুসরণ করে।
3. Function Composition এর উদাহরণ
compose() Method Example:
ধরা যাক, আমাদের একটি String কে uppercase এবং তারপর তার দৈর্ঘ্য বের করতে হবে।
import java.util.function.Function;
public class FunctionCompositionExample {
public static void main(String[] args) {
// Function to convert string to uppercase
Function<String, String> toUpperCase = str -> str.toUpperCase();
// Function to calculate length of the string
Function<String, Integer> getLength = str -> str.length();
// Compose the functions: getLength(toUpperCase(str))
Function<String, Integer> composedFunction = getLength.compose(toUpperCase);
// Apply the composed function
String input = "Hello, Java!";
Integer result = composedFunction.apply(input);
System.out.println("Length of uppercase string: " + result); // Output: 12
}
}
এখানে:
- প্রথমে toUpperCase ফাংশনটি স্ট্রিংয়ের সমস্ত অক্ষরকে বড় হাতের অক্ষরে রূপান্তরিত করে।
- তারপর getLength ফাংশনটি এই নতুন স্ট্রিংয়ের দৈর্ঘ্য বের করে।
- compose() মেথডের মাধ্যমে এই দুটি ফাংশনকে একত্রিত করা হয়।
andThen() Method Example:
ধরা যাক, আমরা একটি স্ট্রিংয়ের দৈর্ঘ্য বের করতে চাই এবং তারপর সেই দৈর্ঘ্যকে দ্বিগুণ করতে চাই।
import java.util.function.Function;
public class FunctionCompositionExample {
public static void main(String[] args) {
// Function to calculate length of the string
Function<String, Integer> getLength = str -> str.length();
// Function to double the length
Function<Integer, Integer> doubleLength = length -> length * 2;
// Compose the functions: doubleLength(getLength(str))
Function<String, Integer> composedFunction = getLength.andThen(doubleLength);
// Apply the composed function
String input = "Hello, Java!";
Integer result = composedFunction.apply(input);
System.out.println("Double of the length: " + result); // Output: 24
}
}
এখানে:
- প্রথমে getLength ফাংশনটি স্ট্রিংয়ের দৈর্ঘ্য বের করে।
- তারপর doubleLength ফাংশনটি সেই দৈর্ঘ্যকে দ্বিগুণ করে।
- andThen() মেথডের মাধ্যমে এই দুটি ফাংশনকে একত্রিত করা হয়।
4. Functional Composition vs. Method Chaining
Functional composition এবং method chaining এর মধ্যে কিছু পার্থক্য রয়েছে:
- Functional Composition ফাংশনাল প্রোগ্রামিংয়ের একটি ধারণা যা compose() এবং andThen() মেথডের মাধ্যমে একাধিক ফাংশন একত্রিত করে। এটি একে অপরের আউটপুট এবং ইনপুট হিসেবে কাজ করে।
- Method chaining হলো একটি প্রক্রিয়া যেখানে একাধিক মেথড একে অপরের উপর কল করা হয়, সাধারণত একটি অবজেক্টের উপর। এটি সাধারণত object-oriented programming এ ব্যবহৃত হয়।
Method Chaining Example:
public class StringBuilderExample {
public static void main(String[] args) {
String result = new StringBuilder("Hello")
.append(", ")
.append("Java!")
.toString();
System.out.println(result); // Output: Hello, Java!
}
}
এখানে, আমরা method chaining ব্যবহার করেছি যেখানে একে অপরের উপর একাধিক মেথড কল করা হয়েছে।
5. Benefits of Functional Composition
- Readability: Function composition কোডের readability বাড়ায়, কারণ আপনি ছোট ছোট ফাংশনগুলিকে একত্রিত করে একটি বড় ফাংশন তৈরি করতে পারেন।
- Reusability: Functional composition ছোট ফাংশনগুলোকে পুনরায় ব্যবহার করার সুযোগ দেয়।
- Modularity: Functional composition উন্নত modularity নিশ্চিত করে, কারণ আপনি ছোট ছোট ফাংশন তৈরি করতে পারেন যেগুলি সহজেই পরীক্ষা করা এবং রক্ষণাবেক্ষণ করা যায়।
- Avoiding Side Effects: Functional composition কোডে side effects কমাতে সহায়ক, কারণ ফাংশনগুলো শুধুমাত্র তাদের ইনপুট দিয়ে কাজ করে এবং ডেটা পরিবর্তন করে না।
Functional Composition Java 8 থেকে পরিচিত একটি শক্তিশালী ফিচার, যা আপনাকে ছোট ফাংশনগুলিকে একত্রিত করে একটি বড় ফাংশন তৈরি করার সুবিধা দেয়। আপনি compose() এবং andThen() মেথডের মাধ্যমে ফাংশনাল কম্পোজিশন ব্যবহার করতে পারেন, যা কোডের রিডেবিলিটি, পুনঃব্যবহারযোগ্যতা এবং মডুলারিটি বাড়ায়। Functional composition ফাংশনাল প্রোগ্রামিংয়ের মূল ধারণা হিসেবে খুবই কার্যকরী এবং সুবিধাজনক।
Read more